package com.ruoyi.common.utils;


import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import java.awt.*;
import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 项目中一些通用工具类 -
 * @author fwx
 * @date 2020/8/2517:33
 */
public class CommonUtils {

    private static Random random = new Random();

    /**
     * 判断集合中某一属性是否存在重复
     * @author fwx
     * @date 2020/8/25 17:34
     */
    public static  <T,U>  boolean judgeAttr(List<T> list, Function<T,U> fun){
        List<U> stringList = list.stream().map(fun)
                .collect(Collectors.toList());
        long count = stringList.stream().distinct().count();

        if (stringList.size() == count) {
            //没有重复元素
            return true;
        }
        return false;
    }

    // 2608.14147  =>  26 +  8.14147 / 60
    public static double getGps(Double gps){

        if(gps == 0){
            return 0;
        }

        String ats = gps.toString();

        String sp1 = ats.substring(0,2);
        String sp2 = ats.substring(2);

        if(gps >= 10000){
            sp1 = ats.substring(0,3);
            sp2 = ats.substring(3);
        }

        double lnn = Integer.parseInt(sp1) + Double.parseDouble(sp2) / 60;
        return lnn;
    }



    //////////////////////////////

    public final static String def =  DatePattern.PURE_DATE_PATTERN;

    /** 标准日期格式：yyyyMMdd */
    public final static String PURE_DATE_PATTERN = "yyyyMMdd"; // DatePattern.PURE_DATE_PATTERN

    /** 标准日期格式：yyyyMMddHHmmss */
    public final static String PURE_DATETIME_PATTERN = "yyyyMMddHHmmss";

    /** 标准日期时间格式，精确到毫秒：yyyy-MM-dd HH:mm:ss.SSS */
    public final static String NORM_DATETIME_MS_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";

    /** 标准日期格式：yyyy-MM-dd */
    public final static String NORM_DATE_PATTERN = "yyyy-MM-dd";

    /** 标准日期格式：yyyyMMddHHmmssSSS */
    public final static String PURE_DATETIME_MS_PATTERN = "yyyyMMddHHmmssSSS";

    /** 标准日期时间格式，精确到秒：yyyy-MM-dd HH:mm:ss */
    public final static String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";


    public final static List<Color> COLORS = new ArrayList<>();

    static {
        COLORS.add(Color.ORANGE);
        COLORS.add(Color.RED);
        COLORS.add(Color.GREEN);
        COLORS.add(Color.CYAN);
        COLORS.add(Color.LIGHT_GRAY);
        COLORS.add(Color.PINK);
        COLORS.add(Color.BLUE);
        COLORS.add(Color.MAGENTA);
        COLORS.add(new Color(185,211,238));
        COLORS.add(new Color(0,139,139));
        COLORS.add(new Color(205,91,69));
        COLORS.add(new Color(160,32,240));
        COLORS.add(Color.BLACK);
    }

    /**
     * 得到计算后日期的格式化字符串
     * @author fwx
     * @date 2020/12/10 10:37
     */
   public static String getDateString(int days,String pattern){
       // 获取当前的日期时间
       LocalDateTime time = LocalDateTime.now().plusDays(days);

       // 日期格式化
       DateTimeFormatter dtf = DateTimeFormatter.ofPattern(pattern);
       return  dtf.format(time);
   }

   /**
    * 计算日期,并格式化
    * @author fwx
    * @date 2022/2/8 17:10
    **/
    public static String  getBeforeTime(Date date,int val,String pattern){
        Calendar beforeTime = Calendar.getInstance();
        beforeTime.setTime(date);
        beforeTime.add(Calendar.DATE, val);// n天后的时间
        Date time = beforeTime.getTime();
        return DateUtils.parseDateToStr(pattern,time);
    }


    /**
     * 根据某一个时间
     * 如: 2-11, 2-15 , 2020-03-05 =>
     *              2-15 - 2-11 = 4 =>
     *                  2020-03-05 - 4 = 2020-03-01 [开始,在第0位]
     *                  2020-03-05 + 1 = 2020-03-06 [开始,在第1位]
     * @author fwx
     * @date 2022/2/9 16:43
     **/
    public static Map<String,String> getRunTime(String startAt, String endAt, Date time) throws Exception{
        int dateBetween = CommonUtils.getDateBetween(startAt, endAt);

        String endAt2    = CommonUtils.getBeforeTime(time, 1, "yyyy-MM-dd");
        String startAt2  = CommonUtils.getBeforeTime(time, -dateBetween , "yyyy-MM-dd");

        Map<String,String> timeMap = new HashMap<>();
        timeMap.put("start",startAt2);
        timeMap.put("end",endAt2);
        return timeMap;
    }


    public static int getDateBetween(String start, String end) {
        Date date1 = DateUtils.parseDate(start, NORM_DATE_PATTERN);
        Date date2 = DateUtils.parseDate(end, NORM_DATE_PATTERN);
        int between = (int)DateUtil.between(date1, date2, DateUnit.DAY);
        return between;
    }


    /**
     * 得到计算后日期的格式化字符串 - 结尾带上周
     * @author fwx
     * @date 2021/3/19 18:00
     **/
    public static String getDateZString(int days,String pattern){
        // 获取当前的日期时间
        LocalDateTime time = LocalDateTime.now().plusDays(days);
        // 日期格式化
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(pattern);
        return  dtf.format(time) + time.getDayOfWeek().getValue();
    }

    /**
     * 得到当前时间 - 带上周信息 - 通讯中使用
     * @author fwx
     * @date 2021/3/19 18:03
     **/
    public static String getDateZString(){
        return getDateZString(0,PURE_DATETIME_PATTERN);
    }

    /**
     *  由日期(格式: 12:10)得到Corn表达式
     */
    public static String getCorn(String date){
        String hour = date.substring(0,2);
        String minute = date.substring(3,5);
        //  */1 * * * * *
        return MessageFormat.format("0 {0} {1} ? * *",minute,hour);
    }

    /**
     * 得到一个开始时间和结束时间的数字
     * @author fwx
     * @date 2022/7/19 18:30
     **/
    public static String[] getDateArr(String start,String end){

        start = start.substring(0,10);
        end =   end.substring(0,10);

        int dateBetween = getDateBetween(start, end);

        DateTime now = DateTime.parse(start);

        int days = dateBetween;
        String[] dateStrs = new String[days];

        for(int i = 0; i < dateBetween; ++i) {
            dateStrs[i] = now.plusDays(i).toString("yyyy-MM-dd");
        }
        return dateStrs;
    }

    /**
     * 返回实体的所有非 null 字段
     * @param source
     * @return
     */
    public static String[] getNullPropertyNames (Object source) {
        try {
            Set<String> emptyNames = new HashSet<>();

            Class<?> clazz = source.getClass();
            Field[] fieldList = clazz.getDeclaredFields();
            for (Field field:fieldList) {
                field.setAccessible(true);
                // 获取字段名称
                String fieldName = field.getName();

                // 获取指定对象的当前字段的值
                Object fieldVal = field.get(source);
                if(null != fieldVal){
                    emptyNames.add(fieldName);
                }
            }
            String[] result = new String[emptyNames.size()];
            return emptyNames.toArray(result);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("获取属性出错");
        }
    }

    public static Random getRandom() {
        return random;
    }

    /**
     * @desc  计算时间 如: 2023-02-01 + 12 => 2023-02-13
     * @author fwx 2023/12/18 16:24
     **/
    public static String computeTime(String time,int day){
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate lt = LocalDate.parse(time, dtf);
        LocalDate localDate = lt.plusDays(day);
        String format = localDate.format(dtf);
        return format;
    }

    /**
     * @desc  计算时间 按年
     * @author fwx 2024/3/7 11:24
     **/
    public static String computeTimeYear(String time,int year){
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate lt = LocalDate.parse(time, dtf);
        LocalDate localDate = lt.plusYears(year);
        String format = localDate.format(dtf);
        return format;
    }

    /**
     * @desc  根据Instant 转为 LocalDateTime
     * @author fwx 2023/11/4 14:44
     **/
    public static LocalDateTime getLocalDateTime(Instant instant){
        LocalDateTime datetime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        return datetime;
    }

    private static String imageDomain = "https://cdbeyond.oss-cn-shanghai.aliyuncs.com";

    /**
     * @desc  得到阿里云图片地址
     * @author fwx 2023/11/10 10:04
     **/
    public static String generateAbsoluteUrl(String relativePath) {
        if (StringUtils.isBlank(relativePath)) {
            return StringUtils.EMPTY;
        }

        if (StringUtils.startsWith(relativePath, "http")) {
            return relativePath;
        }

        return imageDomain + relativePath;
    }




    public static void main(String[] args) {

    }

}
